﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cotizav.CONEXION;
using System.Windows.Forms;
using System.Transactions;
using Cotizav.CONTROLADOR.Otros;
using System.Data;
using System.Data.Linq;

namespace Cotizav
{
    public class CtrlClientes
    {
        private ConexionDataContext conexion;
        private CtrlContactos ctContactos;

        public CtrlClientes()
        {
            ctContactos = new CtrlContactos();
        }
        
        internal List<CLIENTE> getListCliente()
        {
            using (conexion = new ConexionDataContext())
            {
                DataLoadOptions dlo = new DataLoadOptions();
                dlo.LoadWith<CLIENTE>(c => c.CATEGORIA);
                dlo.LoadWith<CLIENTE>(c => c.DISTRITO);
                dlo.LoadWith<CLIENTE>(c => c.CONTACTO);
                dlo.LoadWith<CLIENTE>(c => c.SECTOR);
                dlo.LoadWith<CLIENTE>(c => c.VENDEDOR);
                conexion.LoadOptions = dlo;                    
                
                var query = conexion.CLIENTE.Where(x => x.eliminado == 0);

                return query.ToList();                    
            }
        }

        internal List<CLIENTE> getListCliente(string idVendedor)
        {
            using (conexion = new ConexionDataContext())
            {
                try
                {
                    return conexion.CLIENTE.Where(x => x.idVendedor == idVendedor && x.eliminado == 0).ToList();
                }
                catch (Exception)
                {
                    throw;
                }
            }
        }

        internal DataTable getListClientexVendedor(string idVendedor)
        {
            DataTable result = new DataTable();

            using (conexion = new ConexionDataContext())
            {
                var query = conexion.usp_listarClientexVendedor(idVendedor);

                result.Columns.Add("idVendedor", Type.GetType("System.String"));
                result.Columns.Add("idCliente", Type.GetType("System.String"));
                result.Columns.Add("nombre", Type.GetType("System.String"));
                result.Columns.Add("clienteruc", Type.GetType("System.String"));
                result.Columns.Add("razonSocial", Type.GetType("System.String"));
                result.Columns.Add("direccion", Type.GetType("System.String"));
                result.Columns.Add("telefono", Type.GetType("System.String"));
                result.Columns.Add("nombreDistrito", Type.GetType("System.String"));
                result.Columns.Add("nombreProvincia", Type.GetType("System.String"));
                result.Columns.Add("email", Type.GetType("System.String"));

                DataRow dr;

                foreach (var c in query)
                {
                    dr = result.NewRow();

                    dr[0] = c.idVendedor;
                    dr[1] = c.idCliente;
                    dr[2] = c.nombre;
                    dr[3] = c.clienteruc;
                    dr[4] = c.razonSocial;
                    dr[5] = c.direccion;
                    dr[6] = c.telefono;
                    dr[7] = c.nombreDistrito;
                    dr[8] = c.nombreProvincia;
                    dr[9] = c.email;

                    result.Rows.Add(dr);
                }

                return result;
            } 
        }

        internal List<string> getListRazonSocial()
        {
            throw new System.NotImplementedException();
        }

        internal void registrarCliente(CLIENTE cli)
        {
            using (TransactionScope transactionScope = new TransactionScope())
            {
                using (conexion = new ConexionDataContext())
                {
                    try
                    {
                        //insertamos el id
                        int correlativoCliente = conexion.COTIZAV_CORRELATIVO.Single(x => x.IDENTIFICADOR == "COTIZAV").CLIENTE.Value;
                        string num = Convert.ToString(correlativoCliente);
                        string numero = num.Trim().PadLeft(11, '0');
                        string idCliente = "CLI_" + numero;

                        cli.idCliente = idCliente;
                        cli.eliminado = 0;

                        conexion.CLIENTE.InsertOnSubmit(cli);
                        conexion.SubmitChanges();
                        conexion.increm_ContCliente();
                    }
                    catch(Exception)
                    {
                        throw;
                    }
                }
            }
        }

        internal DialogResult registrarCliente(CLIENTE cli, List<CONTACTO> contactos)
        {
            using (TransactionScope transactionscope = new TransactionScope())
            {
                DialogResult result = DialogResult.Cancel;

                //registramos el cliente
                using (conexion = new ConexionDataContext())
                {
                    try
                    {
                        //insertamos el id
                        int correlativoCliente = conexion.COTIZAV_CORRELATIVO.Single(x => x.IDENTIFICADOR == "COTIZAV").CLIENTE.Value;
                        string num = Convert.ToString(correlativoCliente);
                        string numero = num.Trim().PadLeft(11, '0');
                        string idCliente = "CLI_" + numero;

                        cli.idCliente = idCliente;

                        //insertamos
                        conexion.CLIENTE.InsertOnSubmit(cli);
                        conexion.SubmitChanges();
                        conexion.increm_ContCliente();
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }

                //registramos los contactos
                using (conexion = new ConexionDataContext())
                {
                    try
                    {                        
                        foreach (CONTACTO contact in contactos)
                        {
                            ctContactos.registrarContacto(contact,cli);
                        }

                        transactionscope.Complete();
                        result = DialogResult.OK;
                        return result;
                    }
                    catch (Exception)
                    {                        
                        throw;
                    }
                }               
            }
        }

        internal DialogResult modificarCliente(CLIENTE client, List<CONTACTO> contactos)
        {
            using (TransactionScope transactionscope = new TransactionScope())
            {
                DialogResult result = DialogResult.Cancel;

                //modificamos el cliente
                using (conexion = new ConexionDataContext())
                {

                    try
                    {
                        CLIENTE cli = conexion.CLIENTE.Single(x => x.idCliente == client.idCliente);

                        cli.direccion = client.direccion;
                        cli.email = client.email;
                        cli.razonSocial = client.razonSocial;
                        cli.clienteruc = client.clienteruc;
                        cli.telefono = client.telefono;
                        cli.provincia = client.provincia;
                        cli.idsector = client.idsector;
                        cli.idVendedor = client.idVendedor;
                        cli.idDistrito = client.idDistrito;
                        cli.idSucursal = client.idSucursal;
                        cli.idcategoria = client.idcategoria;
                        cli.email = client.email;
                        cli.fechaModificacion = client.fechaModificacion;

                        conexion.SubmitChanges();
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }

                using (conexion = new ConexionDataContext())
                {
                    try
                    {
                        //verificamos si se han agregado, modificado o eliminado los contactos

                        List<CONTACTO> contactosAgregados = contactos.Where(x => x.statusflag == "I").ToList();
                        List<CONTACTO> contactosEliminados = contactos.Where(x => x.statusflag == "D").ToList();
                        List<CONTACTO> contactosModificados = contactos.Where(x => x.statusflag == "U").ToList();

                        //agregamos los contactos  
                        foreach (CONTACTO conAdd in contactosAgregados)
                        {
                            ctContactos.registrarContacto(conAdd, client);
                        }

                        //modificamos los contactos
                        foreach (CONTACTO conUpd in contactosModificados)
                        {
                            ctContactos.actualizarContacto(conUpd, client);
                        }

                        //eliminamos los contactos 
                        foreach (CONTACTO conDelete in contactosEliminados)
                        {
                            ctContactos.eliminarContacto(conDelete, client);
                        }
                        
                        transactionscope.Complete();
                        result = DialogResult.OK;

                        return result;
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
            }
        }

        internal CLIENTE getCliente(string idCliente)
        {
            using (conexion = new ConexionDataContext())
            {
                try
                {
                    CLIENTE c = conexion.CLIENTE.SingleOrDefault(x => x.idCliente == idCliente && x.eliminado == 0);
                    return c;
                }
                catch (Exception)
                {                    
                    throw;
                }
            }
        }

        internal DialogResult eliminarCliente(CLIENTE cli)
        {
            using (TransactionScope transactionscope = new TransactionScope())
            {
                DialogResult result = DialogResult.Cancel;

                using (conexion = new ConexionDataContext())
                {
                    try
                    {
                        List<CONTACTO> contactos = conexion.CONTACTO.Where(x => x.idcliente == cli.idCliente && x.eliminado == 0).ToList();

                        foreach (CONTACTO con in contactos)
                        {
                            ctContactos.eliminarContacto(con, cli);
                        }
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }

                using (conexion = new ConexionDataContext())
                {
                    try
                    {
                        CLIENTE cliente = conexion.CLIENTE.Single(x => x.idCliente == cli.idCliente && x.eliminado == 0);

                        cliente.eliminado = 1;
                        conexion.SubmitChanges();
                        
                        transactionscope.Complete();
                        result = DialogResult.OK;

                        return result;
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
            }
        }

        internal List<CLIENTE> buscarClienteExacto(string columna, string value)
        {
            using (conexion = new ConexionDataContext())
            {
                List<CLIENTE> result = new List<CLIENTE>();

                try
                {
                    DataLoadOptions dlo = new DataLoadOptions();
                    dlo.LoadWith<CLIENTE>(v => v.VENDEDOR);
                    dlo.LoadWith<CLIENTE>(d => d.DISTRITO);
                    dlo.LoadWith<CLIENTE>(c => c.CATEGORIA);
                    dlo.LoadWith<CLIENTE>(s => s.SECTOR);
                    conexion.LoadOptions = dlo;

                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        switch (columna)
                        {
                            case "razonSocial":
                                result = conexion.CLIENTE.Where(x => x.razonSocial == value).OrderBy(x=>x.razonSocial).ToList();
                                break;
                            case "clienteruc":
                                result = conexion.CLIENTE.Where(x => x.clienteruc == value).OrderBy(x=>x.clienteruc).ToList();
                                break;
                        }
                    }

                    return result;
                }
                catch (Exception)
                {
                    throw;
                }
            }
        }

        internal List<CLIENTE> buscarClienteDentro(string columna, string value)
        {
            using (conexion = new ConexionDataContext())
            {
                List<CLIENTE> result = new List<CLIENTE>();

                try
                {
                    DataLoadOptions dlo = new DataLoadOptions();
                    dlo.LoadWith<CLIENTE>(v => v.VENDEDOR);
                    dlo.LoadWith<CLIENTE>(d => d.DISTRITO);
                    dlo.LoadWith<CLIENTE>(c => c.CATEGORIA);
                    dlo.LoadWith<CLIENTE>(s => s.SECTOR);
                    conexion.LoadOptions = dlo;

                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        switch (columna)
                        {
                            case "razonSocial":
                                result = conexion.CLIENTE.Where(x => x.razonSocial.Contains(value)).OrderBy(x => x.razonSocial).ToList();
                                break;
                            case "clienteruc":
                                result = conexion.CLIENTE.Where(x => x.clienteruc.Contains(value)).OrderBy(x => x.clienteruc).ToList();
                                break;
                        }
                    }
                    else
                    {
                        //retornamos todos los valores
                        result = conexion.CLIENTE.ToList();
                    }

                    return result;
                }
                catch (Exception)
                {
                    throw;
                }
            }
        }

        internal DataTable getListClientexRepGeneral(string ruc, string razonSocial, string idProvincia, string idDistrito, string idSector, string idSucursal)
        {
            DataTable result = new DataTable();

            using (conexion = new ConexionDataContext())
            {
                var query = conexion.usp_listarClientes(ruc, razonSocial, idProvincia, idDistrito, idSector, idSucursal);

                result.Columns.Add("clienteruc", Type.GetType("System.String"));
                result.Columns.Add("razonSocial", Type.GetType("System.String"));
                result.Columns.Add("direccion", Type.GetType("System.String"));
                result.Columns.Add("telefono", Type.GetType("System.String"));
                result.Columns.Add("email", Type.GetType("System.String"));
                result.Columns.Add("nombreProvincia", Type.GetType("System.String"));
                result.Columns.Add("nombreDistrito", Type.GetType("System.String"));
                result.Columns.Add("nombreSector", Type.GetType("System.String"));
                result.Columns.Add("nombreSucursal", Type.GetType("System.String"));

                DataRow dr;

                foreach (var c in query)
                {
                    dr = result.NewRow();

                    dr[0] = c.clienteruc;
                    dr[1] = c.razonSocial;
                    dr[2] = c.direccion;
                    dr[3] = c.telefono;
                    dr[4] = c.email;
                    dr[5] = c.nombreProvincia;
                    dr[6] = c.nombreDistrito;
                    dr[7] = c.nombreSector;
                    dr[8] = c.nombreSucursal;

                    result.Rows.Add(dr);
                }

                return result;
            }
        }
    }
}

